package cn.tedu.micro.demo.redis;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 测试容器中的bean对象
 * 所以这个类加载必须在spring启动之后
 * spring-boot-starter-test已经完成了工作
 */
@SpringBootTest(classes = RedisDemo.class)
public class RedisTestDemo3 {
    @Autowired
    private RedisTemplate redisTemplate;
    //geoadd stations lng lat memeber
    @Test
    public void testGeoAdd() {
        //组织一个 集合 表示 场站信息地理位置
        String key = "stations";
        String member1 = "station01";
        Point point1 = new Point(110, 20);
        String member2 = "station02";
        Point point2 = new Point(120, 30);
        String member3 = "station03";
        Point point3 = new Point(130, 40);

        //拿到geo类型的子对象
        GeoOperations geoOps = redisTemplate.opsForGeo();
        //geoLocation 有2个封装属性name(元素值) point 绑定坐标
        RedisGeoCommands.GeoLocation geoLocation1 = new RedisGeoCommands.GeoLocation<>(member1,point1);
        RedisGeoCommands.GeoLocation geoLocation2 = new RedisGeoCommands.GeoLocation<>(member2,point2);
        RedisGeoCommands.GeoLocation geoLocation3 = new RedisGeoCommands.GeoLocation<>(member3,point3);
        geoOps.add(key,geoLocation1);
        geoOps.add(key,geoLocation2);
        geoOps.add(key,geoLocation3);
    }

    //geoDist key member1 member2 可以查询2个元素之间的距离
    @Test
    public void geoDist() {
        String key = "stations";
        String member1 = "station01";
        String member2 = "station02";
        String member3 = "station03";
        //查询 station01 station02距离
        GeoOperations geoOps = redisTemplate.opsForGeo();
        Distance dist = geoOps.distance(key, member1, member2);
        //value  距离数字
        //unit 距离单位
        System.out.println("距离:"+dist.getValue()+dist.getUnit());
        //第二个distance重载方法 可以指定单位 m|km|ft|mi
    }

    //测试geoRadius
    @Test
    public void testGeoRadius(){
        //georadius stations 50 50 50000 km withdist withcoord
        String key="stations";
        GeoOperations geoOps = redisTemplate.opsForGeo();
        Circle circle=new Circle(50.0,50.0,50000000);
        //添加2个选项 withDist withCoord
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        args.includeDistance();//withdist
        args.includeCoordinates();//withcoord
        GeoResults allResults = geoOps.radius(key,circle,args);
        //解析results 解析station01(dist,point) station02 station03
        //1.解析从allResults对象获取results
        List<GeoResult<RedisGeoCommands.GeoLocation<String>>> results = allResults.getContent();
        for (GeoResult<RedisGeoCommands.GeoLocation<String>> geoResult : results) {
            //每循环一个geoResult都能拿到一个命中元素 而且可以获取元素的距离中心点位移
            double dist = geoResult.getDistance().getValue();
            System.out.println("命中元素距离中心点:"+dist);
            geoResult.getDistance().getUnit();//和你查询的选项一样 m

            //拿到绑定坐标
            Point point = geoResult.getContent().getPoint();
            System.out.println("命中元素绑定坐标:"+point.getX()+","+point.getY());

            //存储的字符串元素值
            String member = geoResult.getContent().getName();
            System.out.println("命中元素值:"+member);
        }
        return;
    }
}
